// Test
package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

func (interp *Interpreter) command(args []string) {
	bafuncs := interp.InitSysFuncs()
	interp.Init()
	interp.BasicFuncs = bafuncs

	fmt.Println("\n##########################开始测试###############################")

	//fmt.Println(lines)
	//fmt.Println("=====================================================")
	//code.ParseLine(lines)
	source := NewSource(args[0])
	fmt.Println(args[0])

	fmt.Println("All Tokens:")
	for _, token := range source.tokens {
		fmt.Print(token, " ")
	}
	code := NewCode(source.tokens, source.module)
	module := code.ProcessModule(interp)

	fmt.Println("\n*************************开始执行***********************************")
	// mainfunc1 := mainfunc.(*DrFunction)

	// 		call := interp.NewFuncCall2(mainfunc1, 0, 0)
	// 		call.module = interp.startModule
	// 		call.locals = interp.locals
	/////////////////////////////////////////////////

	func0 := module.members["main"].(*DrFunction)
	call := interp.NewFuncCall(func0)
	call.module = func0.module
	interp.CallFunction(call, nil, 0)

}
func (interp *Interpreter) Interative() {
	// defer func() {
	// 	err := recover()
	// 	if err != nil {
	// 		fmt.Println("err:", err)
	// 		interp.Interative()
	// 	}

	// }()

	bafuncs := interp.InitSysFuncs()
	interp.Init()
	interp.BasicFuncs = bafuncs
	interp.startModule = interp.NewModule()

	var line string
	for {
		//fmt.Print("请您输入一条语句\n>>")
		fmt.Print("\n:")
		reader := bufio.NewReader(os.Stdin)
		line, _ = reader.ReadString('\n')
		fmt.Println(line)
		line = strings.Trim(line, "\n")
		line = strings.Trim(line, "\r")

		if line == "quit" || line == "exit" || line == "q" {
			break
		}
		source := new(DrSource)
		source.module = "startup"
		source.Scan3(line, 0)

		tokens := source.tokens
		code := new(DrCode)
		code.tokens = tokens
		//fmt.Println(tokens)
		mod := code.ProcessModule(interp)
		for k, value := range mod.members {
			if k == "main" {
				continue
			}
			interp.startModule.members[k] = value
		}

		mainfunc := mod.members["main"]
		if mainfunc == nil {
			continue
		}

		//clause := new(DrClause)
		//clause.funcName = "main" //main函数不带参数
		//call := interp.NewFuncCall(clause, 0, 0)
		//call.module = interp.startModule
		//call.locals = interp.locals

		///////////////////////////////////
		mainfunc1 := mainfunc.(*DrFunction)

		call := interp.NewFuncCall(mainfunc1)
		call.module = interp.startModule
		call.locals = interp.locals
		//root:=new(DrObject)

		/////////////////////////////////////////////////
		cls := mainfunc1.Clauses
		for _, cl := range cls {
			call.module = interp.startModule
			ob, _ := interp.ExecuteGenerateClause(cl, call, 0)
			if ob != nil {
				interp.PrintSet = make(map[IObject]int)
				ob.Print(interp)
				fmt.Println()
			}
			fmt.Println("当前的局部变量：")
			for k, v := range call.locals {
				interp.PrintSet = make(map[IObject]int)
				fmt.Print(k, " ")
				v.Print(interp)
				fmt.Println()
			}
		}
	}
}

/*****************************************************************/
func main() {
	interp := new(Interpreter)
	interp.Functions = make(map[string]*DrFunction)
	test := 6
	switch test {
	case 1:
		{

		}
	case 2:
		{
			fmt.Println("Please enter something:")
			//reader := bufio.NewReader(os.Stdin)

		}
	case 3:
		{
			// code := new(DrCode)
			// sss := "sumv += cos(12.3+x*(i + y)* addNum ( a , b ) ) + (n_12+sin(34.5))"
			// //sss := "c=a+b*2"
			// code.Scan3(sss, 0)
			// fmt.Println(code.tokens, len(code.tokens))

			// //formula := strings.Split(sss, " ")
			// //formula = code.tokens
			// //comma := string(",")
			// code.tokenList = code.tokens
			// clause := code.ParseClause2()
			// fmt.Println("最后一行")
			// clause.Print()
		}
	case 4:
		{
			// code := new(DrCode)
			// code.AddToken("\n")

			// reader := liuyh.NewTxtReader("liu.drg")
			// lines := reader.ReadLines()
			// reader.Close()
			// //fmt.Println(lines)
			// //fmt.Println("=====================================================")
			// //code.ParseLine(lines)
			// code = new(DrCode)
			// for _, line := range lines {
			// 	if line == "\n" || line == "" {
			// 		continue
			// 	}

			// 	code.Scan3(line, 0)
			// }
			// fmt.Println("All Tokens:")
			// for _, token := range code.tokens {
			// 	fmt.Print(token, " ")
			// }
			// code.tokenList = code.tokens
			//code.ProcessCode(interp)

		}
	case 5:
		{
			fmt.Println("********************开始函数调用***********************")

			//interp.Functions = make(map[string]*Function)

			bafuncs := interp.InitSysFuncs()
			interp.Init()
			interp.BasicFuncs = bafuncs

			fmt.Println("\n##########################开始测试###############################")

			//fmt.Println(lines)
			//fmt.Println("=====================================================")
			//code.ParseLine(lines)
			source := NewSource("test1.drg")

			fmt.Println("All Tokens:")
			for _, token := range source.tokens {
				fmt.Print(token, " ")
			}
			code := NewCode(source.tokens, source.module)
			module := code.ProcessModule(interp)

			fmt.Println("\n*************************开始执行***********************************")
			///////////////////////////////////
			mainfunc := module.members["main"]
			mainfunc1 := mainfunc.(*DrFunction)

			call := interp.NewFuncCall(mainfunc1)
			call.module = module
			call.locals = interp.locals
			call.Name = "main"
			//root:=new(DrObject)

			/////////////////////////////////////////////////

			//clause := new(DrClause)
			//clause.funcName = "main" //main函数不带参数了
			//call := interp.NewFuncCall(clause, 0, 0)
			//call.module = module
			//root:=new(DrObject)

			interp.CallFunction(call, nil, 0)

		}
	case 6: //进入交互模式
		{
			fmt.Println("\n******************欢迎使用龙语(英文代号：Dragon)编程*********************")
			fmt.Println("    龙语言(名称为暂定，英文Dragon)解释器是一个类Python的脚本语言解释器。 ")
			fmt.Println("当前阶段是使用Go语言开发的，这样做是为了利用Go中现成的数据结构，比直接使用 ")
			fmt.Println("C语言开发要省力得多。而未来理想的发展目标是采用C或C++来编写，以尽可能实现 ")
			fmt.Println("自主设计，减少对国外技术的依赖。该解释器当前可以看作是一个原型系统，经过一段 ")
			fmt.Println("时间的发展后，若能够稳定运行，则可以考虑以此为基础，翻译为基于C++版本的新解释器，")
			fmt.Println("甚至有可能发展出一个真正能产生机器码的编译器。而编译器的最终实现超出了本设计者的")
			fmt.Println("能力范围(非科班出身)，今后有赖于大众贡献开源代码来完成. Dragon语言的发展目标是开发一个")
			fmt.Println("中国人自主的数值计算环境，类似于Python和Matlab。")
			fmt.Println("    欢迎您来使用和测试，并提出宝贵建议，新语言的完善离不开您的帮助。目前基础")
			fmt.Println("函数库很不完善，请您谅解。有关异常处理、类、调用动态链接库的功能将在")
			fmt.Println("未来的发展中陆续添加。暂无精力撰写语法标准，您就参考着Python的语法，把Python")
			fmt.Println("中冒号去掉，然后全部把代码块用{}包装起来。不需考虑代码缩进问题.")
			fmt.Println("当前只发布一个初步的交互式解释器版本，将来可以将交互性得更易用些(类似于ipython的效果)")
			fmt.Println("\n设计者：河南理工大学资源环境学院 刘永和(非计算机科班人员，主要研究方向为气象")
			fmt.Println("资料分析与流域水文模拟)")
			fmt.Println("\n特此声明：本解释器的开发纯属个人爱好，无任何公司和商业背景，也无任何机构资助.")
			fmt.Println("\n请输入dir()来查看当前的内建函数名(与Python内建函数基本相似)")
			//interp.command(os.Args)
			if len(os.Args) < 2 {
				fmt.Println("\n已进入交互模式，如想进入代码文件执行模式，请在命令行中执行dragon.exe，以待执行的脚本程序文件名作为命令行参数。")
				interp.Interative()
			} else {
				fmt.Println(os.Args[1])
				interp.command(os.Args[1:])
			}
		}

	}
}
